package limit;

import java.util.Date;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

import com.google.common.util.concurrent.RateLimiter;

public class RateLimiterDemo {

	
	 public static void main(String[] args) {
	       // testNoRateLimiter();
	        testWithRateLimiter();
	    }
	    public static void testNoRateLimiter() {
	        long start = System.currentTimeMillis();
	        for (int i = 0; i < 10; i++) {
	            System.out.println("call execute.." + i);
	        }
	        long end = System.currentTimeMillis();
	        System.out.println(end - start);
	    }
	    public static void testWithRateLimiter() {
	    	ExecutorService executorService = Executors.newCachedThreadPool();//线程池
	    	
	        long start = System.currentTimeMillis();
	        RateLimiter limiter = RateLimiter.create(1.0);//每秒往桶里放5个令牌
	        // 每秒不超过10个任务被提交 
	        for (int i = 0; i < 10; i++) {
	            //limiter.acquire();//拿一个令牌去干活,如果没令牌了阻塞等待
	            boolean tryAcquire = limiter.tryAcquire(1, 1, TimeUnit.SECONDS);//拿一个令牌去干活,如果没令牌了阻塞等待1秒后false
	            // 请求RateLimiter, 超过permits会被阻塞 
	            if (tryAcquire) {
	            	System.out.println("call execute..limit" + i);
		            CompletableFuture.supplyAsync(()->calc(1),executorService);
				}else {
					System.out.println("获取令牌等待超时,不执行了");
				}
	            
	        }
	        long end = System.currentTimeMillis();
	        System.out.println(end - start);
	    }
	    
	    public static Integer calc(Integer i) {
	        try {
	            if (i == 1) {
	                Thread.sleep(3000);//任务1耗时3秒
	            } else if (i == 5) {
	                Thread.sleep(5000);//任务5耗时5秒
	            } else {
	                Thread.sleep(1000);//其它任务耗时1秒
	            }
	            System.out.println("task线程：" + Thread.currentThread().getName()
	                    + "任务i=" + i + ",完成！+" + new Date());
	        } catch (InterruptedException e) {
	            e.printStackTrace();
	        }
	        return i;
	    }
}
